package com.fdb.efp.flow.executor.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.fdb.efp.flow.common.constance.FlowConstance;
import com.fdb.efp.flow.common.vo.EngineVO;
import com.fdb.efp.flow.executor.util.AliGenericServiceCallUtil;
import com.fdb.efp.flow.service.vo.BizFlowTaskParamVO;
import com.fdb.efp.flow.service.vo.BizPluginServiceVO;
import com.fdb.efp.flow.service.vo.InstFlowTaskVO;
import com.fdb.basic.framework.core.exception.FlowException;
import com.fdb.basic.framework.core.exception.PauseException;
import com.fdb.basic.framework.core.exception.TerminateException;
import com.fdb.basic.framework.core.util.StringUtil;

/**
 * 
 * 服务插件执行器
 * 
 * @author Cytus_
 * @since 2018年5月14日 下午2:27:00
 * @version 1.0
 *
 */
@Service("servicePluginTaskExecutor")
public class ServicePluginTaskExecutor extends AbstractPluginTaskExecutor {

	private static Logger logger = LoggerFactory.getLogger(ServicePluginTaskExecutor.class);
	
	public EngineVO doTask(EngineVO evo, InstFlowTaskVO task) throws Exception {
		
		logger.info("节点实例号:"+ evo.getNodeInstanceId() +", 任务编号："+ evo.getTaskId() +"执行当前任务服务插件开始......");
		
		try {
			//服务插件相关信息判断及获取
			if (StringUtil.isEmpty(task.getBizPluginId())) {
				logger.error("任务编号:"+ evo.getTaskId() +"类型为服务, 但尚未进行配置!");
				throw new FlowException("任务编号:"+ evo.getTaskId() +"类型为服务, 但尚未进行配置!");
			}
			if (StringUtil.isEmpty(task.getBizPluginMethodName())) {
				BizPluginServiceVO bizPluginVo = getBizPluginServiceByPluginId(task.getBizPluginId());
				if (Objects.isNull(bizPluginVo)) {
					logger.error("服务ID:"+ task.getBizPluginId() +"尚未进行配置!");
					throw new FlowException("服务ID:"+ task.getBizPluginId() +"尚未进行配置!");
				}
				task.setBizPluginMethodName(bizPluginVo.getBizPluginMethodName());
			}
			
			//查询当前插件配置的出入参参数信息并按照参数类型分别放到出参list和入参list中
			List<BizFlowTaskParamVO> listParams = getTaskParamsByTaskId(task.getTaskId());
			List<BizFlowTaskParamVO> inParams = new ArrayList<BizFlowTaskParamVO>();
			List<BizFlowTaskParamVO> outParams = new ArrayList<BizFlowTaskParamVO>();
			if (Objects.nonNull(listParams)) {
				for (BizFlowTaskParamVO paramVo : listParams) {
					if (FlowConstance.PLUGIN_IN_PARAM.equals(paramVo.getBizParamIo())) {
						inParams.add(paramVo);
					} else {
						outParams.add(paramVo);
					}
				}
			}
			
			this.dealDefaultParam(evo, inParams);
			//hsf 泛型调用参数组装
			Object[] params = new Object[inParams.size()];
			String[] classType = new String[inParams.size()];
			inParams.parallelStream().forEach(s -> {
				params[s.getInParamOrder() - 1] = getPluginValue(evo.getPluginVo(), s.getBizTargetParamCode());
				classType[s.getInParamOrder() - 1] = s.getParamClass().split("@")[0];
			
			});
			
			try {
			    AliGenericServiceCallUtil.aliGenericServiceCall(evo, task, classType, params, outParams);
			} catch (TerminateException | PauseException e) {
			    logger.warn("节点实例号:"+ evo.getNodeInstanceId() +", 任务编号："+ evo.getTaskId() +", 执行服务插件："+ task.getBizServiceClass() +", 方法:"+ task.getBizPluginMethodName() +"出现暂停或终止提示, cause by:"+ e.getMessage());
			    throw e;
			} catch (Exception e) {
				logger.error("节点实例号:"+ evo.getNodeInstanceId() +", 任务编号："+ evo.getTaskId() +", 执行服务插件："+ task.getBizServiceClass() +", 方法:"+ task.getBizPluginMethodName() +"异常!", e);
				throw e;
			}
			evo.setTaskExecuteStatus(FlowConstance.TASK_STATUS_END);
		} catch (TerminateException | PauseException e) {
            throw e;
        } catch (Exception e) {
			logger.info("节点实例号:"+ evo.getNodeInstanceId() +", 任务编号："+ evo.getTaskId() +"执行当前任务服务插件出现异常!", e);
			evo.setTaskExecuteStatus(FlowConstance.TASK_STATUS_EXCEPTION);
			throw e;
		}
		logger.info("节点实例号:"+ evo.getNodeInstanceId() +", 任务编号："+ evo.getTaskId() +"执行当前任务服务插件结束......");
		return evo;
	}
	
}
